package com.mes.eventhandler;

import com.basis.utils.HibernateDao;
import com.basis.utils.StringUtil;
import com.mes.data.EmesPBomItem;
import com.mes.data.EmesPBomItemMete;
import com.mes.data.EmesSize;
import org.openbravo.base.exception.OBException;
import org.openbravo.base.model.Entity;
import org.openbravo.base.model.ModelProvider;
import org.openbravo.base.model.Property;
import org.openbravo.client.kernel.event.*;
import org.openbravo.dal.core.OBContext;
import org.openbravo.dal.service.OBDal;
import org.openbravo.database.ConnectionProvider;
import org.openbravo.erpCommon.utility.Utility;
import org.openbravo.service.db.DalConnectionProvider;
import javax.enterprise.event.Observes;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public class EmesPbomItemEventHandler extends EntityPersistenceEventObserver {
	private static Entity[] entities = { ModelProvider.getInstance().getEntity(EmesPBomItem.ENTITY_NAME) };

	@Override
	protected Entity[] getObservedEntities() {
		return entities;
	}

	public void onUpdate(@Observes EntityUpdateEvent event) {
		if (!isValidEvent(event)) {
			return;
		}
		changeDataSetName(event);
	}

	//新建头信息时同时保存BomItem
	public void onSave(@Observes EntityNewEvent event) {
		if (!isValidEvent(event)) {
			return;
		}
		changeDataSetName(event);
	}

	private void changeDataSetName(EntityPersistenceEvent event) {
		final EmesPBomItem bomItem = (EmesPBomItem) event.getTargetInstance();
		//判断如果部位、物料、名称都没有填写，则抛出错误
		if ("BW".equalsIgnoreCase(bomItem.getLevel())) {
			if (bomItem.getEmesComponent() == null) {
				throwMessage("部位不能为空！");
			} else if (bomItem.getParent() != null) {
				throwMessage("部位不能挂在其他BOM项下！");
			}
		}
		final Property nameProperty = entities[0].getProperty(EmesPBomItem.PROPERTY_NAME);
		if ("KXX".equalsIgnoreCase(bomItem.getLevel())) {
			if ((StringUtil.isEmpty(bomItem.getName()) || StringUtil.isEmpty(bomItem.getCode()))) {
				throwMessage("名称、编码不能为空！");
			}
			if (checkCodeName(bomItem)) {
				throwMessage("相同部位底下的可选项编码或名称已存在！");
			}
		} else if ("WL".equalsIgnoreCase(bomItem.getLevel())) {
			if (bomItem.getProduct() == null) {
				throwMessage("物料不能为空！");
			}
			event.setCurrentState(nameProperty, bomItem.getProduct().getName());
			setSizeMete(bomItem);
		} else if ("BW".equalsIgnoreCase(bomItem.getLevel())) {
			event.setCurrentState(nameProperty, bomItem.getEmesComponent().getName());
		}
	}

	public void onDelete(@Observes EntityDeleteEvent event) {
		if (!isValidEvent(event)) {
			return;
		}
	}

	private void throwMessage(String message){
		String language = OBContext.getOBContext().getLanguage().getLanguage();
		ConnectionProvider conn = new DalConnectionProvider(false);
		throw new OBException(Utility.messageBD(conn, message, language));
	}

	/**
	 * 根据标准用量设置其他尺码用量
	 */
	private void setSizeMete(EmesPBomItem bomItem) {
		if (bomItem.getQty() != null && bomItem.getEmesPBomItemMeteList().isEmpty() && bomItem.getLossCoefficient() != null) {
			List<EmesSize> list = OBDal.getInstance().createQuery(EmesSize.class, "where active = true order by code asc").list();
			EmesPBomItemMete mete = null;
			BigDecimal qty = bomItem.getQty();
			BigDecimal loss = bomItem.getLossCoefficient();
			float standardSize = Float.parseFloat(HibernateDao.getParameterValue("STANDARD_SIZE"));
			int sub = 5;
			if (standardSize < 50) {
				sub = 1;
			}
			BigDecimal value = null;

			for (EmesSize size : list) {
				mete = new EmesPBomItemMete();
				mete.setEmesSize(size);
				value = qty.add(new BigDecimal((Float.parseFloat(size.getCode()) - standardSize) / sub).multiply(loss));
				mete.setQty(value);
				mete.setUom(bomItem.getUom());
				mete.setEmesPbomItem(bomItem);

				bomItem.getEmesPBomItemMeteList().add(mete);
			}
		}
	}

	/**
	 * 限制相同部位下可选项，编码、名称不能相同
	 */
	private boolean checkCodeName(EmesPBomItem bomItem) {
		String sql = "select count(*) count0 from emes_pbom_item pi " +
				" where pi.level = 'KXX' " +
				"	and (name = ? or code = ?) " +
				"	and pi.parent_id = ? " +
				"	and emes_pbom_item_id <> ?";
		Map<String, Object> result = HibernateDao.queryUnique(sql, bomItem.getName(),
				bomItem.getCode(), bomItem.getParent().getId(), bomItem.getId());
		if (result != null) {
			if (Integer.parseInt(result.get("COUNT0").toString()) > 0) {
				return true;
			}
		}
		return false;
	}
}
